package org.ccay.manage.security.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Named;

import org.ccay.core.base.BatchVO;
import org.ccay.core.base.PageVO;
import org.ccay.core.base.PagedResult;
import org.ccay.manage.security.dao.IRoleDao;
import org.ccay.manage.security.service.IRoleManageService;
import org.ccay.security.dao.IRoleDimensionDataProviderDao;
import org.ccay.security.entity.Role;
import org.ccay.security.util.SecurityUtil;
import org.ccay.security.vo.RoleVO;
@Named
public class RoleManageService implements IRoleManageService {

	@Inject
	private IRoleDao roleDao;
	
	@Inject
	private IRoleDimensionDataProviderDao roleDimensionDataProviderDao;
	
	@Override
	public Role findRoleById(Long roleId) {
		return roleDao.findRoleById(roleId);
	}

	@Override
	public PagedResult<RoleVO> findPagedRoles(RoleVO role, PageVO page) {
		return roleDimensionDataProviderDao.findPagedRoles(role,page);
	}
	
	@Override
	public List<RoleVO> findRoleByIds(List<Long> roleIds){
		return roleDimensionDataProviderDao.findRoleByIds(roleIds);
	}
	
	@Override
	public Role findRoleByName(String roleName) {
		return roleDao.findRoleByName(roleName);
	}

	
	

	@Override
	public Boolean checkReferenced(Long roleId) {
		List<Long> roleIds = new ArrayList<Long>();
		roleIds.add(roleId);
		return !roleDao.checkReferenced(roleIds).isEmpty();
	}

	@Override
	public void delRoleCascade(Long roleId) {
		roleDao.delRoleCascade(roleId);
	}

	@Override
	public void delRole(Long roleId) {
		roleDao.delRole(roleId);
	}

	@Override
	public void createRole(Role role) {
		roleDao.createRole(role);
	}
	
	@Override
	public void updateRole(Role role) {
		roleDao.updateRole(role);
	}

	@Override
	public void batchOperation(BatchVO<RoleVO> batchItems) {
		Map<String, Object> validateInfo = validateForBatch(batchItems);
		List<String> nameUnique = (List<String>)validateInfo.get("NameUniqueFail");
		if(null == nameUnique || nameUnique.isEmpty()){
			if(!batchItems.getItems2Delete().isEmpty()){
				SecurityUtil.checkPermission("roleManagement:delRoleCascade");
				deleteRolesCascade(batchItems.getItems2Delete());
			}
			if(!batchItems.getItems2Create().isEmpty()){
				SecurityUtil.checkPermission("roleManagement:create");
				createRoles(batchItems.getItems2Create());
			}
			if(!batchItems.getItems2Update().isEmpty()){
				SecurityUtil.checkPermission("roleManagement:delete");
				updateRoles(batchItems.getItems2Update());
			}
		}
	}
	
	@Override
	public Boolean checkRolenameUnique(String roleName, Long roleId) {
		return roleDao.checkUserNamesUnique(roleName,roleId) == 0;
	}
	
	/**
	 * 批量操作校验
	 * @param batchItems
	 * @return
	 */
	@Override
	public Map<String,Object> validateForBatch(BatchVO<RoleVO> batchItems){
		Map<String,Object> errorInfo = new HashMap<String,Object>();
		if(!batchItems.getCreateAndUpdateUnion().isEmpty()){
			//校验提供的新增及修改用户名是否本身重复
			Set<String> names = new HashSet<String>();
			for(RoleVO row : batchItems.getCreateAndUpdateUnion()){
				if(names.contains(row.getName())){
					getListInMap(errorInfo,"NameUniqueFail",String.class).add(row.getName());
				}else{
					names.add(row.getName());
				}
			}
			//与数据库中已存在的数据校验用户名是否重复
			List<String> errorNames = roleDao.checkUserNamesUnique(batchItems);
			if(!errorNames.isEmpty()){
				getListInMap(errorInfo,"NameUniqueFail",String.class).addAll(errorNames);
			}
		}
		
		if(!batchItems.getItems2Delete().isEmpty()){
			//校验角色是否被引用
			Map<Long,String> deleteRoles = new HashMap<Long,String>();
			for(RoleVO delRow : batchItems.getItems2Delete()){
				deleteRoles.put(delRow.getId(), delRow.getName());
			}
			List<Long> ids = roleDao.checkReferenced(new ArrayList<Long>(deleteRoles.keySet()));
			if(!ids.isEmpty()){
				Set<String> set = getListInMap(errorInfo,"RoleReferenced",String.class);
				for(Long id : ids){
					set.add(deleteRoles.get(id));
				}
			}
		}
		return errorInfo;
	}
	
	@SuppressWarnings("unchecked")
	private <T> Set<T> getListInMap(Map<String,Object> map, String type,Class<T> T){
		Set<T> set = (Set<T>)map.get(type);
		if(set == null){
			set = new HashSet<T>();
			map.put(type, set);
		}
		return set;
	}
	@Override
	public void createRoles(List<RoleVO> items2Create) {
		roleDao.createRoles(items2Create);
	}
	
	@Override
	public void updateRoles(List<RoleVO> items2Update) {
		roleDao.updateRoles(items2Update);
	}
	
	@Override
	public void deleteRolesCascade(List<RoleVO> items2Delete) {
		List<Long> ids = new ArrayList<Long>();
		for(RoleVO vo : items2Delete){
			ids.add(vo.getId());
		}
		roleDao.deleteRolesCascade(ids);
	}

	
}
